﻿using System;
using ParserGenerator.Output;
using ParserGenerator.SyntacticAnalysis;

namespace ParserGenerator.ScannerConstruction
{
    [Serializable]
    public sealed class ScannerAutomatonTextWriter
    {
        public IndentedWriter Writer { get; }

        public ScannerAutomatonTextWriter(IndentedWriter writer)
        {
            if (writer == null)
                throw new ArgumentNullException(nameof(writer));
            Writer = writer;
        }

        private void WriteScannerAutomatonState(ScannerAutomatonState state)
        {
            if (state == null)
                throw new ArgumentNullException(nameof(state));
            Writer.Write(state.Number);
            if (state.Core != null)
                Writer.Write(" : {0}", state.Core);
            Writer.Write("\n{0}", new string('-', 40));
            foreach (ScannerAutomatonTransition tran in state.Transitions.Values)
                Writer.Write("\n{0}", tran);
            if (state.Reductions.Count > 0)
            {
                if (state.Transitions.Count > 0)
                    Writer.Write("\n");
                Writer.Write("\nreductions:");
                foreach (LexicalRuleDeclarator rule in state.Reductions)
                    Writer.Write("\n  {0}", rule);
            }
            if (state.Predecessors.Count > 0)
            {
                Writer.Write("\n\npredecessors:\n");
                foreach (ScannerAutomatonState pred in state.Predecessors)
                    Writer.Write("  {0}", pred.Number);
            }
        }

        public void WriteScannerAutomaton(ScannerAutomaton automaton)
        {
            if (automaton == null)
                throw new ArgumentNullException(nameof(automaton));
            for (int i = 0; i < automaton.States.Count; i++)
            {
                if (i > 0)
                    Writer.Write("\n\n");
                WriteScannerAutomatonState(automaton.States[i]);
            }
        }
    }
}
